import java.math.BigInteger;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;

/**
 * This is the basic user class It is responsible for storing the username,
 * password hash, name, and the suspend state of the user account
 */
public class User {

	private String username;
	private String encrypted_password;
	public PasswordHash passwordHash; // PasswordHash of the submitted password
	private Name name;
	private boolean suspended;
	private PasswordHash passwordHelper = new PasswordHash();
	// what kind of user instance(nurse, doctor, patient, sysAdmin)
	private int accessLevel;

	public static int accessPatient = 0;
	public static int accessNurse = 1;
	public static int accessDoctor = 2;
	public static int accessSysAdmin = 3;

	/**
	 * This is the main constructor for the user class
	 * 
	 * @param username
	 *            the username for this instance
	 */
	public User(String username, String encrypted_password, Name name, int level) {
		this.username = username;
		this.encrypted_password = encrypted_password;
		this.name = name;
		this.accessLevel = level;
		this.suspended = false;
	}

	public User() {
		this.username = null;
		this.passwordHash = null;
		this.name = null;
		this.accessLevel = 0;
		this.suspended = false;
	}

	/**
	 * Returns the user's username
	 * 
	 * @return the user's username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * Sets the user's username
	 * 
	 * @param username
	 *            the new username
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * Tests if a hash matches the user's PasswordHash
	 * 
	 * @param testPasswordHash
	 *            a hash string
	 * @return true if this PasswordHash matches the user's PasswordHash
	 */
	public boolean hasPasswordHash(String testPasswordHash) {
		return this.passwordHash.getValue().equals(testPasswordHash);
	}

	/**
	 * Sets the PasswordHash for the user
	 * 
	 * @param hash
	 *            the PasswordHash for the user
	 */
	public void setPasswordHash(PasswordHash hash) {
		this.passwordHash = hash;
	}

	/**
	 * Returns the name of the user
	 * 
	 * @return the name of the user
	 */
	public Name getName() {
		return name;
	}

	public String getEncryptedPassword() {
		return this.encrypted_password;
	}

	public void setEncryptedPassword(String password) {
		this.encrypted_password = password;
	}

	/**
	 * Sets the name of the user
	 * 
	 * @param name
	 *            the name of the user
	 */
	public void setName(Name name) {
		this.name = name;
	}

	/** this method returns the access level of a user */
	public int getAccessLevel() {
		return accessLevel;
	}

	/** this method sets the access level of a user */
	/**
	 * @param level
	 *            the access level of a user
	 */
	public void setAccessLevel(int level) {
		this.accessLevel = level;
	}

	/**
	 * Checks to see if the user's account is suspended
	 * 
	 * @return true if the user is suspended, false otherwise
	 */
	public boolean isSuspended() {
		return suspended;
	}

	/**
	 * Sets the suspend state of the user account
	 * 
	 * @param state
	 *            the state being set
	 */
	public void setSuspendState(boolean state) {
		this.suspended = state;
	}

	// Read
	public static Collection<User> readFromName(Name name) {
		Collection<User> returnvar = new ArrayList<User>();
		String sql = "SELECT * FROM Name WHERE title='" + name.getTitle()
				+ "' OR first_name='" + name.getFirstName()
				+ "' OR middle_name='" + name.getMiddleName()
				+ "' OR last_name='" + name.getLastName() + "'";
		ResultSet rs = Database.selectQuery(sql);
		try {
			while (rs.next()) {
				String foundUsername = rs.getString("username");
				returnvar.add(User.readUser(foundUsername));
			}
		} catch (Exception e) {
		}
		return returnvar;
	}

	// read
	public static User readUser(String username) {
		String foundPass = "";
		int foundAccess = 0;
		String sql = "SELECT * FROM Users WHERE username='" + username + "'";
		ResultSet rs = Database.selectQuery(sql);
		// should only be 1 record per username
		try {
			while (rs.next()) {
				foundPass = rs.getString("encrypted_password");
				foundAccess = rs.getInt("access_level");
			}
		} catch (Exception e) {
		}
		// get the name of the patient
		Name userName = Name.readName(username);
		User foundUser = new User(username, foundPass, userName, foundAccess);
		return foundUser;
	}

}
